package com.solbox.sbhlsexam;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.solbox.hls2rtsp.*;
import com.solbox.sbhlsexam.R;
import com.google.analytics.tracking.android.*;

/*
 * thread for just updating(time position, etc..) and hiding UI(if 5 seconds without any events),
 * 
 */
class SBHLSTimer extends Thread {
	
	private boolean m_break = false;				// flag to stop thread
	private SBHLSExamActivity m_activity = null;
	
	public void prepareJoin() {
		
		this.m_break = false;
	}
	
	public void start(SBHLSExamActivity activity) {
		
		
		this.m_activity = activity;
		this.m_break = true;
		 
		super.start();
		
		
		
	}
	
	public void run() {
		
		while(this.m_break) { 
			
			this.m_activity.updateUI();
			this.m_activity.hideUI(false);
			
			try {
				
				Thread.sleep(500);	// check UI per 500ms.
			} catch (InterruptedException e) { }
		}
		
	}
}

public class SBHLSExamActivity extends Activity implements Hls2RtspRouterListener, SurfaceHolder.Callback, OnBufferingUpdateListener, OnErrorListener, OnCompletionListener, OnPreparedListener, OnSeekCompleteListener, OnVideoSizeChangedListener {
	
 
	private Hls2RtspRouter m_router = null;		// RTSP route server (from SBHLS library) 
	private SBHLSTimer m_timer = null;
	private String m_url = null;				// HLS(HTTP live streaming) URL (from intent data)
	private TextView m_buffer_gauge = null;		// gauge for the amount of buffer
	private ImageView m_play_btn = null;		// play/pause/stop button
	private SurfaceHolder m_surface = null;		// surface holder of video view
	
	private long m_last_ui_keepon = 0;			// base time to be shown UI continuously.
	
	private int m_screen_width = 0;				// width of screen(device)
	private int m_screen_height = 0;			// height of screen(device)
	
	private boolean m_router_ready = false;		// flag for checking whether server is ready or not.
	private boolean m_hide_option = false;		// flag for passing option to runnable object. see hideUI()
	private char m_checking_resume = 0;			// 1 = under preparing. 2 = under seeking. see resumeVideo() 
	
	private boolean m_now_play = false;			// flag for checking whether media player is playing or not.
	private MediaPlayer m_playback = null; 		// media player
		
	/*
	 * convert time position to string
	 * (static function)
	 */
    static protected String getTimeCode(int tt) {
    	
    	String str = "";
    	int hh, mn, ss;
    	
    	hh = tt / 3600;
    	if(hh > 99) hh = 99;
    	
    	mn = (tt % 3600) / 60;
    	ss = (tt % 60);
    	
    	if(hh < 10) str = "0" + hh + ":";
    	else str = hh + ":";
    	
    	if(mn < 10) str = str + "0" + mn + ":";
    	else str = str + mn + ":";
    	
    	if(ss < 10) str = str + "0" + ss;
    	else str = str + ss;
    	
    	return str;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		//EasyTracker.getInstance().activityStart(this);
		
		// get the url from web browser  
        // this.m_url = getIntent().getDataString();
		
		//example HLS URL
		this.m_url = "http://livebr.sambatech.com.br/hls-live/livepkgr/otv_0d70d1758596a48ba8f9f119080b9fb4/liveevent/livestream.m3u8";

    	requestWindowFeature(Window.FEATURE_NO_TITLE);
    	getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    	// get screen size
		DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		
		this.m_screen_width = metrics.widthPixels;
		this.m_screen_height = metrics.heightPixels;

		// layout with resource  
        setContentView(R.layout.main);

        this.m_buffer_gauge = (TextView)findViewById(R.id.bufgaze);
        this.m_play_btn = (ImageView)findViewById(R.id.playbtn);

        //change play button as disabled status(opacity=100%) at start time 
        this.m_play_btn.setAlpha(64);

        this.m_surface = ((SurfaceView)findViewById(R.id.vw)).getHolder();
        
        ((SBSeekingBar)findViewById(R.id.playback)).setActivity(this);
        
        // initialize surface
        if(this.m_surface != null) {
        	this.m_surface.addCallback(this);
        	this.m_surface.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
    }

	/*
     * start RTSP route server
     */
    private boolean startRouter() {
    	
   		this.m_router = new Hls2RtspRouter();
   		this.m_router.setListener(this);

   		// set adapted bandwidth = 2Mbps 300kbps
   		this.m_router.setBandwidth(2000000);
   		
   		// set listen port of RTSP server = 18554
   		this.m_router.setRTSPPort(18554);
    		
   		// set to hold buffer until media player connects.
       	this.m_router.setHoldBuffer(true);
       	
       	// set license key of SBHLS library
       	this.m_router.setID("DEMO");
       	this.m_router.setKey("6fc853b157ece0895b4a43a4bf547c12");

    	// set HLS URL
      	this.m_router.setURL(this.m_url);

       	// if SBHLS library not support this device,
       	if(this.m_router.isSupport() == Hls2RtspRouter.IS_NOT_SUPPORTED) {
    	
       		// release RTSP route server
       		this.releaseRouter(true);
    		return false;
    	}

       	// show loading animation
       	((ImageView) findViewById(R.id.loading)).setVisibility(View.VISIBLE);
    	((AnimationDrawable)((ImageView) findViewById(R.id.loading)).getBackground()).start();
      	
    	// start server
      	if(this.m_router.start() == false) {
      		
      		// if failed, 
      		
      		// stop loading animation
        	((ImageView) findViewById(R.id.loading)).setVisibility(View.GONE);
        	((AnimationDrawable)((ImageView) findViewById(R.id.loading)).getBackground()).stop();
      		
        	// release RTSP route server
      		this.releaseRouter(true);
      		return false;
      		
      	} else {
      		
      		// if success, start SBHLSTimer thread.
      		this.m_timer = new SBHLSTimer();
      		this.m_timer.start(this);
      	}
      	      	
    	return true;
    }
    
    /*
     *  release RTSP route server
     *  
     *  @param ui	if true, update server status UI.
     */
    private void releaseRouter(boolean ui) {
    
    	this.m_router_ready = false;
    	
    	// release SBHLSTimer thread
    	if(this.m_timer != null) {
    		
    		try {
    		
    			// stop thread
    			this.m_timer.prepareJoin();
    			this.m_timer.join();
    			
    		} catch (InterruptedException e) { }
    		
    		this.m_timer = null;
    	}
    	
    	// release RTSP route server
    	if(this.m_router != null) {
    		
    		this.m_router.stop();
    		this.m_router = null;
    	}
    	
    	if(ui) {
    		
    		// set buffer amount = 0
    		this.m_buffer_gauge.setText("  0%");
    		
    		// hide stream type display (at upper panel)
    		findViewById(R.id.liveon).setVisibility(View.GONE);
    		findViewById(R.id.vodon).setVisibility(View.GONE);
    		
    		// hide UI
    		this.hideUI(true);
    	}
    }
    
    /*
     * start media player
     */
    private void startPlayback() {
    	EasyTracker.getInstance().activityStart(this);
    	// release media player, if already allocated.
    	this.releasePlayback(true);
    	
    	// create media player object
    	this.m_playback = new MediaPlayer();
    	
    	// mark that is under preparing,..
		this.m_checking_resume = 1;
		
		// set listener
    	this.m_playback.setOnBufferingUpdateListener(this);
    	this.m_playback.setOnCompletionListener(this);
    	this.m_playback.setOnPreparedListener(this);
    	this.m_playback.setOnErrorListener(this);
    	this.m_playback.setOnSeekCompleteListener(this);
    	this.m_playback.setOnVideoSizeChangedListener(this);
    	
    	// set audio output type
    	this.m_playback.setAudioStreamType(AudioManager.STREAM_MUSIC);
    	    	    	
    	try {
    		
    		// link to RTSP route server (at local host)
    		// * path of URL does not matter anything. (in this example, is 'sbhls.sdp')
    		this.m_playback.setDataSource("rtsp://127.0.0.1:18554/sbhls.sdp");
    		
    		// set surface
        	this.m_playback.setDisplay(this.m_surface);
        	
        	// set to keep screen on while playing
        	this.m_playback.setScreenOnWhilePlaying(true);
    		
    	} catch(Exception e) {}
		
    		/*
    		 *  At some device, 
    		 *  prepareAsync() method may not operated in asynchronous method exactly.
    		 *  for this reason, call in post.
    		 */
	    	findViewById(R.id.vw).post(new Runnable() {
				
				public void run() {
					
					if(m_playback != null) {
						
						try {

							m_playback.prepareAsync();
				        	
							
						} catch(Exception e) {}
					}
					
				}
			});
    }
    
    /*
     * release media player
     * 
     * @param ui	if true, update player status UI.
     */
    private void releasePlayback(boolean ui) {
    	EasyTracker.getInstance().activityStop(this);
    	// set flag = is not playing
    	this.m_now_play = false;
    	    	
    	// terminate resume monitor of SBHLS library
    	if(this.m_router != null) {
    		
    		this.m_router.termResumeMonitor();
    	}
    	
    	// release media player
    	if(this.m_playback != null) {
    		
    		this.m_playback.stop();
    		this.m_playback.release();
    		
    		this.m_playback = null;
    	}
    	
    	if(ui) {
    		
	    	findViewById(R.id.bottom_ui).post(new Runnable() {
				
				public void run() {
					
					// setting for replay button
					
						// swap to play image (ready state)
			    		m_play_btn.setImageResource(R.drawable.play);
			    	
			    		//change play button as enabled status(opacity=100%) 
			    		m_play_btn.setAlpha(255);

	    	        // show logo
			    	findViewById(R.id.cut).setVisibility(View.VISIBLE);
			    			 
			    	// reset time position info
			    	((TextView)findViewById(R.id.total_t)).setTypeface(Typeface.MONOSPACE, Typeface.NORMAL);
			    	((TextView)findViewById(R.id.total_t)).setText("--:--:--");
					((TextView)findViewById(R.id.current_t)).setTextColor(0xFFFFFFFF);
					((TextView)findViewById(R.id.current_t)).setText("00:00:00");
					
					// reset time position cursor
					((SBSeekingBar)findViewById(R.id.playback)).setPos(0);
					
					// reset seeking UI
					((SBSeekingBar)findViewById(R.id.playback)).setVOD(false, 0);
					
					// hide loading animation
					((ImageView) findViewById(R.id.loading2)).setVisibility(View.GONE);
			    	((AnimationDrawable)((ImageView) findViewById(R.id.loading2)).getBackground()).stop();
					
				}
			});
    	}
    }
    
    /*
     * go to twitter web page (@hlsplayer)
     */
    protected void twit() {
    	
		Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://mobile.twitter.com/hlsplayer"));
		startActivity(intent);
		
		this.finish();
    }
    
    /*
     * show UI
     */
    protected synchronized void showUI() {
    	
    	if(this.m_last_ui_keepon == 0) {
    		
    		// update base time to begin show UI
    		this.m_last_ui_keepon = System.currentTimeMillis();
    		
    		// show UI panel with sliding animation
			TranslateAnimation top_trans = new TranslateAnimation(
					TranslateAnimation.ABSOLUTE, 0.0f, 
					TranslateAnimation.ABSOLUTE, 0.0f, 
					TranslateAnimation.ABSOLUTE, -92.0f, 
					TranslateAnimation.ABSOLUTE, 0.0f);
			
			top_trans.setDuration(100);
			top_trans.setInterpolator(new LinearInterpolator());
			top_trans.setFillAfter(true);
			
			((FrameLayout)findViewById(R.id.top_ui)).startAnimation(top_trans);
    		((FrameLayout)findViewById(R.id.top_ui)).setVisibility(FrameLayout.VISIBLE);
    		
			TranslateAnimation btm_trans = new TranslateAnimation(
					TranslateAnimation.ABSOLUTE, 0.0f, 
					TranslateAnimation.ABSOLUTE, 0.0f, 
					TranslateAnimation.ABSOLUTE, 64.0f, 
					TranslateAnimation.ABSOLUTE, 0.0f);
			
			btm_trans.setDuration(100);
			btm_trans.setInterpolator(new LinearInterpolator());
			btm_trans.setFillAfter(true);
			
			((FrameLayout)findViewById(R.id.bottom_ui)).startAnimation(btm_trans);
    		((FrameLayout)findViewById(R.id.bottom_ui)).setVisibility(FrameLayout.VISIBLE);

    		if(this.m_router == null) {

    			// if route server released, hide stream type display (at upper panel) 
				findViewById(R.id.liveon).setVisibility(View.GONE);
				findViewById(R.id.vodon).setVisibility(View.GONE);

    		} else {
    			
    			if(this.m_router.isLive()) { // if stream type is live
    			
    				findViewById(R.id.liveon).setVisibility(View.VISIBLE);
    				findViewById(R.id.vodon).setVisibility(View.GONE);
    			
    			} else { // if stream type is VOD
    			
    				findViewById(R.id.liveon).setVisibility(View.GONE);
    				findViewById(R.id.vodon).setVisibility(View.VISIBLE);
    			}
    		}
    		
    		// check WiFi status
    		if(((WifiManager)this.getApplicationContext().getSystemService(Context.WIFI_SERVICE)).isWifiEnabled()) {
    			
    			findViewById(R.id.wifion).setVisibility(View.VISIBLE);
    			
    		} else {
    			
    			findViewById(R.id.wifion).setVisibility(View.GONE);
    		}
    		
    	} else {
    		
    		// if UI already shown, update base time only
    		this.m_last_ui_keepon = System.currentTimeMillis();
    	}
    }
    
    /*
     * hide UI
     * @param force		if true, it means hide by user. otherwise it means hide by timer thread 
     */
    protected synchronized void hideUI(boolean force) {
    	
    	if(this.m_last_ui_keepon != 0) {
    		
    		long ct = System.currentTimeMillis();
    		
    		// if by user or 5 seconds over base time
    		if(force || (ct - this.m_last_ui_keepon >= 5000 && ((SBSeekingBar)findViewById(R.id.playback)).underSeeking() == false)) {
    	
    			this.m_hide_option = force;
    			
    			findViewById(R.id.top_ui).post(new Runnable() {
    				
    				public void run() {
    					
    					// hide UI panel with sliding animation
    					TranslateAnimation top_trans = new TranslateAnimation(0.0f, 0.0f, 0.0f, -92.0f);
    					
    					top_trans.setDuration(m_hide_option == true ? 100 : 500);
    					top_trans.setInterpolator(new LinearInterpolator());
    					top_trans.setFillAfter(true);
    					
    					((FrameLayout)findViewById(R.id.top_ui)).startAnimation(top_trans);
    					((FrameLayout)findViewById(R.id.top_ui)).setVisibility(FrameLayout.INVISIBLE);
    					
    					TranslateAnimation btm_trans = new TranslateAnimation(0.0f, 0.0f, 0.0f, 64.0f);
    					
    					btm_trans.setDuration(m_hide_option == true ? 100 : 500);
    					btm_trans.setInterpolator(new LinearInterpolator());
    					btm_trans.setFillAfter(true);
    					
    					((FrameLayout)findViewById(R.id.bottom_ui)).startAnimation(btm_trans);
    					((FrameLayout)findViewById(R.id.bottom_ui)).setVisibility(FrameLayout.INVISIBLE);		
    				}
    			});
    			
    			// reset base time 
    			this.m_last_ui_keepon = 0;
    		}
    	}
    }
    
    /*
     * update UI
     */
    protected void updateUI() {
    	
    	findViewById(R.id.top_ui).post(new Runnable() {
    		
    		public void run() {
    			
    			if(m_router_ready) { // if route server is running,
    				
    				// update buffer status
    				
    				String str = "";
    				
    				float dur = m_router.getBufferAmount(Hls2RtspRouter.BUFFER_AMOUNT_TYPE_DURATION);
    				dur = (float) (dur * 100.0 / (m_router.getHlsTargetDuration() * 4.0));
    		
    				if(dur > 100.0) dur = (float) 100.0;
    		
    				if(dur < 100.0) str = str + " ";
    				if(dur < 10.0) str = str + " ";
    		
    				str = str + (int)dur + "%";
    				m_buffer_gauge.setText(str);
    				
    			} else {
        		
    				// reset buffer status
    				m_buffer_gauge.setText("  0%");
    			}
			
				if(m_checking_resume == 0 && m_now_play && m_playback != null) { // if under playing
						
					// update current time position
					
					int pos = m_playback.getCurrentPosition();
					
					((TextView)findViewById(R.id.current_t)).setText(getTimeCode(pos / 1000));
					((SBSeekingBar)findViewById(R.id.playback)).setPos(pos / 1000);
				}
				
				// update WiFi status
				if(((WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE)).isWifiEnabled()) {
			
					findViewById(R.id.wifion).setVisibility(View.VISIBLE);
			
				} else {
			
					findViewById(R.id.wifion).setVisibility(View.GONE);
				}
    			
    		}
    			
    	});
    	
    }
    
    /*
     * check whether UI is visible or not.
     */
    protected boolean isVisibleUI() {
    	
    	if(this.m_last_ui_keepon == 0) return false;
    	
    	return true;
    }    
    
    /*
     * change(seek) time position 
     * 
     * called from SBPlaybackView
     * 
     * @param pos		target time position (seconds)
     * @param activate	if false, just update UI (temporary).  
     */
    protected synchronized void seek(int pos, boolean activate) {
    	
    	if(activate) {
    		
    		// from blue color to white color, if dragging before
    		((TextView)findViewById(R.id.current_t)).setTextColor(0xFFFFFFFF);
			
    		if(this.m_playback != null) {

    			if(pos >= 0) {
    				
    				// set with target time position
    				((TextView)findViewById(R.id.current_t)).setText(getTimeCode(pos));
    				
    				// show loading animation
    		    	((ImageView) findViewById(R.id.loading2)).setVisibility(View.VISIBLE);
    		    	((AnimationDrawable)((ImageView) findViewById(R.id.loading2)).getBackground()).start();
    				    		    	
    		    	//change play button as disabled status(opacity=100%) during seeking 
    		    	this.m_play_btn.setAlpha(64);

    		    	// mark that is under seeking,.. 
    		    	this.m_checking_resume = 2;
    		    	
    		    	// start resume monitor of SBHLS library
    		    	this.m_router.startResumeMonitor(this.m_playback, false);
    		    	
    		    	// seek (call seek method of media player)
    				this.m_playback.seekTo(pos * 1000);
    				
    			} else {
    				
    				// set with current time position when canceled
    				((TextView)findViewById(R.id.current_t)).setText(getTimeCode(this.m_playback.getCurrentPosition() / 1000));
    			}
    		} 
    		
    	} else {
    		
    		// just update time position UI
    		// it used for showing target time position when dragging cursor.
    		((TextView)findViewById(R.id.current_t)).setTextColor(0xFF4184E9);	// blue color
    		((TextView)findViewById(R.id.current_t)).setText(getTimeCode(pos));
    	}
    }
    
    /*
     * onClick event handler of close button
     */
    public void doCloseButton(View view) {
    	
    	EasyTracker.getInstance().activityStop(this);
    	
		this.releasePlayback(false);
		this.releaseRouter(false);

		this.finish();
    }    
    
    /*
     *  onClick event handler of play button
     */
    public void doPlayButton(View view) {
    	EasyTracker.getInstance().activityStart(this);
    	// if under seeking or preparing, ignore
    	if(this.m_checking_resume != 0) return;
    	
    	if(this.m_router == null) { // if ready state,
    		
    		//change play button as enabled status(opacity=100%) during preparing.
    		this.m_play_btn.setAlpha(64);

    		// restart RTSP route server
    		this.startRouter();		
    		return;
    	}
    	
    	if(this.m_router.isLive()) { 
    		
    		// if stream type is live, just supply stop function.
    		
    		if(this.m_playback != null && this.m_playback.isPlaying()) {
    			
    			this.releasePlayback(true);
    			this.releaseRouter(true);
    		}
    		return;
    	}
    	
    	// if stream type is VOD, supply play & pause function.
    	if(this.m_playback != null) {
    		
    		if(this.m_playback.isPlaying()) {
    			
    			this.m_playback.pause();
    			
    		} else {
    			
    			this.m_playback.start();
    		}
    	} 
    	
    	// swap image as state
    	if(this.m_playback != null && this.m_playback.isPlaying()) {
    		
    		// if playing, swap to pause image
    		this.m_play_btn.setImageResource(R.drawable.pause);
    		
    	} else {

    		// if paused or stopped, swap to play image
    		this.m_play_btn.setImageResource(R.drawable.play);
    	}

    }    
    
    /*
     * check whether under seeking(or preparing) or not
     */
    public boolean underSeeking() {
    	
    	return this.m_checking_resume != 0 ? true : false;
    }
    
    
    public void surfaceCreated(SurfaceHolder holder) {
    	
    	// start RTSP route server (start receiving HLS)
    	this.startRouter();
    }

    
    public void surfaceChanged(SurfaceHolder surfaceholder, int width, int height, int format) {

    }
    
    
    public void surfaceDestroyed(SurfaceHolder surfaceholder) {
    	
    }
    
   
	public void onReset() {
		
    	// currently not supported
	}

   
	public void onReady() {
   	
		this.m_router_ready = true;
		
		// start playing
		this.startPlayback();
	}
    
    
	public void onChangeBandwidth(int bandwidth) {
		
	}
	
   
	public void onRejected(int code) {
		
	}
	
    @Override
	protected void onStop() {
    	EasyTracker.getInstance().activityStop(this);
    	// activity stop
    	
		this.releasePlayback(false);
		this.releaseRouter(false);
		EasyTracker.getInstance().activityStop(this);
		super.onStop();
	}
    
    @Override
	public boolean onTouchEvent(MotionEvent event) {

    	if(event.getAction() == MotionEvent.ACTION_DOWN) {
    		
			// show/hide UI panel
			if(this.isVisibleUI()) {
				
				this.hideUI(true);
				
			} else {
				
				this.showUI();	
				
			}
    	}
		
		return super.onTouchEvent(event);
	}    
	
   
	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		
	}
	
    
	public boolean onError(MediaPlayer mp, int what, int extra) {
	
    	return false;
	}
	
    
	public void onCompletion(MediaPlayer mp) {

    	// at error or end of stream
    	
		this.releasePlayback(true);
		this.releaseRouter(true);
	}
		
   
	public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
	

		
	}
	
  
	public void onPrepared(MediaPlayer mp) {

    	/*
    	 *  realign surface's layout by aspect ratio of video stream.
    	 */
		int w,h;
		FrameLayout.LayoutParams lp = null;

		w = this.m_router.getVideoWidth();
		h = this.m_router.getVideoHeight();
		
		this.m_surface.setFixedSize(w,h);
		
		if(h < this.m_screen_height) {
			
			w = this.m_screen_height * w / h;
			h = this.m_screen_height;
		}
		
		if(w > this.m_screen_width) {
			
			h = this.m_screen_width * h / w;
			w = this.m_screen_width;
		}
		
		lp = new FrameLayout.LayoutParams(w, h, Gravity.CENTER);
		findViewById(R.id.vw).setLayoutParams(lp);
		///////////////////////////////////////////////////////////

		// start resume monitor of SBHLS library.
		this.m_router.startResumeMonitor(m_playback, true);
		
		// start playing
		this.m_playback.start();
		
		// set flag = is playing
		this.m_now_play = true;

		if(this.m_router.isLive()) {
		
			// if stream type is live, swap to stop image
			this.m_play_btn.setImageResource(R.drawable.stop);

		} else {
			
			// if stream type is VOD, swap to pause image
			this.m_play_btn.setImageResource(R.drawable.pause);
		}
		
		if(!this.m_router.isLive()) { // if stream type is VOD
			
			int pos = m_playback.getDuration() / 1000;

			// some device, may not support duration (return 0)
			// if so, can query to RTSP route server 
			if(pos <= 0) pos = (int)m_router.getDuration();
			
			// update duration 
			((TextView)findViewById(R.id.total_t)).setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
			((TextView)findViewById(R.id.total_t)).setText(getTimeCode(pos));
			
			// update seeking UI
			((SBSeekingBar)findViewById(R.id.playback)).setVOD(true, pos);
			
		} else {
			
			((SBSeekingBar)findViewById(R.id.playback)).setVOD(false, 0);
		}
		
		// show UI panel automatically.
		this.showUI();
	}

	
	public void onSeekComplete(MediaPlayer mp) {
		
		// do nothing (ignore)
		// resume monitor of SBHLS library replace this event
	}


	/*
	 * seeking(or preparing) completed.
	 * checked by resume monitor of SBHLS library. 
	 */
	public void onPlaybackResume() {
		//EasyTracker.getInstance().activityStart(this);
    	findViewById(R.id.vw).post(new Runnable() {
        	
    		public void run() {
    			
    			if(m_checking_resume == 1) { // preparing completed
    			
    				// hide loading animation
    				((ImageView) findViewById(R.id.loading)).setVisibility(View.GONE);
    				((AnimationDrawable)((ImageView) findViewById(R.id.loading)).getBackground()).stop();
    				
    				// hide logo
    				findViewById(R.id.cut).setVisibility(View.GONE);
    				
    			} else { // seeking completed
    				
    				// hide loading animation
    				((ImageView) findViewById(R.id.loading2)).setVisibility(View.GONE);
    				((AnimationDrawable)((ImageView) findViewById(R.id.loading2)).getBackground()).stop();
    			}
    	    	
    			((TextView)findViewById(R.id.current_t)).setTextColor(0xFFFFFFFF);
    			
    			// change play button as enabled status(opacity=100%)
    			m_play_btn.setAlpha(255);
    			
    	        if(m_playback != null) {
    	        	
    	        	// update time position UI (with current time position)
    	        	((SBSeekingBar)findViewById(R.id.playback)).setSeekPos(-1, false);
    	        	((SBSeekingBar)findViewById(R.id.playback)).setPos(m_playback.getCurrentPosition() / 1000);
    	        }
    			
    	        // mark that is playing
    			m_checking_resume = 0;
    		}
    	});
	}
	
}


